package com.pic.mgt.haishin.executer;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import org.springframework.dao.DataAccessException;

import com.pic.mgt.dao.haishin.AppointedHaishinAsgmtMessageDao;
import com.pic.mgt.dao.haishin.AppointedHaishinBusinessAsgmtActionDao;
import com.pic.mgt.executer.IGXTypeExecutionException;
import com.pic.mgt.haishin.unit.AppointedAsgmtOkHaishinMessageUnit;
import com.pic.mgt.haishin.unit.AppointedTargetOkHaishinMessageUnit;
import com.pic.mgt.haishin.unit.HaishinMessage;
import com.pic.mgt.unit.operation.UnitOperationException;


public final class AppointedHaishinMessageUnitExecuter extends
		HaishinMessageUnitExecuter {
	
	private AppointedHaishinAsgmtMessageDao appointedHaishinAsgmtMessageDao;
	private AppointedHaishinBusinessAsgmtActionDao appointedHaishinBusinessAsgmtActionDao;
	
	@Override
	protected void executeIGXType() throws IGXTypeExecutionException {
		HaishinMessage haishinMessage = (HaishinMessage)super.unit;
		
		/*
		 * 訊息有分二種:
		 * (1) 取得 target file 解出來檔案的訊息
		 * (2) 取得指示檔的訊息
		 */
		
		if (AppointedTargetOkHaishinMessageUnit.class.isInstance(haishinMessage)) {
			// 代表是取得 target file 解出來的檔案
			
			// 更新資料庫
			try {
				// 新增 target message 資料
				super.insertTargetMessage(haishinMessage);
				// 更新 business target action 的最後交易時間
				super.updateBusinessTargetActionTxTime(haishinMessage);
			} catch (DataAccessException e) {
				throw new IGXTypeExecutionException(
						"Updating appointed haishin target transaction '" + haishinMessage.getTransactionFilename() +
						"' record to database faild." ,e);
			}
			
			// 移除 Confirmation File (Message 的 Confirmation File,不是 Transaction File的)
			try {
				// throws UnitOperationException
				super.simpleMessageUnitOperation.removeConfirmationFile(haishinMessage);
			} catch (UnitOperationException e) {
				throw new IGXTypeExecutionException(
						"Haishin message '" + haishinMessage.getUnitName() +
						"' execution failed in removing message file process" ,e);
			}
		}
		else if(AppointedAsgmtOkHaishinMessageUnit.class.isInstance(haishinMessage)) {
			// 代表是取得指示檔
			
			// 更新資料庫
			try {
				// 新增資料 (table: appointed_haishin_asgmt_message)
				Map<String, Object> inserValuesMap = getDBInsertBasicValuesMap(haishinMessage);
				// throws DataAccessException
				this.appointedHaishinAsgmtMessageDao.insertBasic(inserValuesMap);
				
				// 更新資料 (table: appointed_haishin_business_asgmt_action)
				this.appointedHaishinBusinessAsgmtActionDao.
						updateLastTxTimeByTxFilename(new java.sql.Timestamp(haishinMessage.getTransactionTime().getTime()),
													 haishinMessage.getTransactionFilename());
			} catch (DataAccessException e) {
				throw new IGXTypeExecutionException(
						"Updating appointed haishin asgmt transaction '" + haishinMessage.getTransactionFilename() +
						"' record to database faild." ,e);
			}
			
			/*
			 *  移除 Message File 
			 *  (包含 Confirmation File,
			 *  	 Confirmation File For Transaction File,
			 *       Transaction File
			 *  三個檔)
			 */
			try {
				// throws UnitOperationException
				super.simpleMessageUnitOperation.removeUnit(haishinMessage);
			} catch (UnitOperationException e) {
				throw new IGXTypeExecutionException(
						"Haishin message '" + haishinMessage.getUnitName() +
						"' execution failed in removing message file process" ,e);
			}
		}
	}
	
	private Map<String, Object> getDBInsertBasicValuesMap(HaishinMessage haishinMessage) {
		Map<String ,Object> insertValuesMap = new HashMap<String, Object>();

		insertValuesMap.put(AppointedHaishinAsgmtMessageDao._confirmationFile, haishinMessage.getConfirmationFilename());
		insertValuesMap.put(AppointedHaishinAsgmtMessageDao._transactionFile, haishinMessage.getTransactionFilename());
		insertValuesMap.put(AppointedHaishinAsgmtMessageDao._transactionTime, new Timestamp(haishinMessage.getTransactionTime().getTime()));
		insertValuesMap.put(AppointedHaishinAsgmtMessageDao._unitName, haishinMessage.getUnitName());
		insertValuesMap.put(AppointedHaishinAsgmtMessageDao._terminalId, haishinMessage.getTerminalId());

		return insertValuesMap;
	}
	
	// --- getter and setter ---

	public void setAppointedHaishinAsgmtMessageDao(
			AppointedHaishinAsgmtMessageDao appointedHaishinAsgmtMessageDao) {
		this.appointedHaishinAsgmtMessageDao = appointedHaishinAsgmtMessageDao;
	}

	public void setAppointedHaishinBusinessAsgmtActionDao(
			AppointedHaishinBusinessAsgmtActionDao appointedHaishinBusinessAsgmtActionDao) {
		this.appointedHaishinBusinessAsgmtActionDao = appointedHaishinBusinessAsgmtActionDao;
	}
}
